package main

import (
	"context"
	"encoding/json"
	"fmt"
	"hxzkx/global/bao"
	"hxzkx/global/model"
	"hxzkx/global/pkg"
	location "hxzkx/kitex_gen/hertz/location"
	"strconv"
	"time"
)

// LocationServiceImpl implements the last service interface defined in the IDL.
type LocationServiceImpl struct{}

// LocationByIp implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) LocationByIp(ctx context.Context, req *location.LocationByIpReq) (resp *location.LocationByIpResp, err error) {
	// TODO: Your code here...
	count_key := fmt.Sprintf("%d:getLocationByIp:count", req.UserId)
	key := fmt.Sprintf("%d:getLocationByIp", req.UserId)
	count, _ := model.RDB.Get(model.Ctx, count_key).Int()
	if count >= 3 {
		return &location.LocationByIpResp{}, fmt.Errorf("目前请求数量已上限，五分钟后再试")
	}
	model.RDB.Incr(model.Ctx, count_key)
	if count == 2 {
		model.RDB.Expire(model.Ctx, count_key, time.Minute*5)
	}
	var ip model.GetAddressById
	data, _ := model.RDB.Get(model.Ctx, key).Result()
	if data == "" {
		ip, err = pkg.GetAddressByIP(req.Ip)
		if err != nil {
			return nil, err
		}
		var Log = model.LocationRecord{
			Ip:     req.Ip,
			UserId: int(req.UserId),
			LetLng: fmt.Sprintf("%s,%s", ip.Content.Point.X, ip.Content.Point.Y),
		}
		err = bao.InsertLocationRecord(Log)
		if err != nil {
			return nil, err
		}
		set, _ := json.Marshal(&ip)
		model.RDB.Set(model.Ctx, key, set, time.Minute*10)
	} else {
		json.Unmarshal([]byte(data), &ip)
	}
	let, _ := strconv.ParseFloat(ip.Content.Point.X, 64)
	lng, _ := strconv.ParseFloat(ip.Content.Point.Y, 64)
	resp = &location.LocationByIpResp{
		Address: ip.Address,
		Let:     float32(let),
		Lng:     float32(lng),
	}
	return
}

// LocationData implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) LocationData(ctx context.Context, req *location.LocationDataReq) (resp *location.LocationDataResp, err error) {
	// TODO: Your code here...
	address, err := pkg.GetAddress(req.Name, req.Location)
	if err != nil {
		return nil, err
	}

	resp = &location.LocationDataResp{
		Address: address.Results[0].Address,
		Let:     float32(address.Results[0].Location.Lat),
		Lng:     float32(address.Results[0].Location.Lng),
	}
	return
}

// CommonLocationAdd implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) CommonLocationAdd(ctx context.Context, req *location.CommonLocationAddReq) (resp *location.CommonLocationAddResp, err error) {
	// TODO: Your code here...
	var CommonLocation model.CommonLocation
	var DB = model.DB.Model(&model.CommonLocation{})
	DB.Where("user_id = ? and let_lng = ?", req.UserId, req.Location).Find(&CommonLocation)
	if CommonLocation.ID != 0 {
		return nil, fmt.Errorf("该地址已记录")
	}
	var count int64
	DB.Where("user_id = ?", req.UserId).Count(&count)
	if count >= 10 {
		return nil, fmt.Errorf("个人记录点已全部使用")
	}
	CommonLocation = model.CommonLocation{
		LetLng:   req.Location,
		NickName: req.Name,
		UserId:   int(req.UserId),
	}
	if err = model.DB.Create(&CommonLocation).Error; err != nil {
		return nil, err
	}
	resp = &location.CommonLocationAddResp{}
	return resp, nil
}

// CommonLocationDel implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) CommonLocationDel(ctx context.Context, req *location.CommonLocationDelReq) (resp *location.CommonLocationDelResp, err error) {
	// TODO: Your code here...
	model.DB.Where("id = ?", req.Id).Delete(&model.CommonLocation{})
	return
}

// CommonLocationUpdate implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) CommonLocationUpdate(ctx context.Context, req *location.CommonLocationUpdateReq) (resp *location.CommonLocationUpdateResp, err error) {
	// TODO: Your code here...
	var CommonLocation model.CommonLocation
	var DB = model.DB.Model(&model.CommonLocation{})
	DB.Where("id = ?", req.Id).Find(&CommonLocation)
	if req.Location != "" {
		CommonLocation.LetLng = req.Location
	}
	if req.Name != "" {
		CommonLocation.NickName = req.Name
	}
	DB.Save(&CommonLocation)
	return
}

// CommonLocationList implements the LocationServiceImpl interface.
func (s *LocationServiceImpl) CommonLocationList(ctx context.Context, req *location.CommonLocationListReq) (resp *location.CommonLocationListResp, err error) {
	// TODO: Your code here...
	var CommonLocation []model.CommonLocation
	var DB = model.DB.Model(&model.CommonLocation{})
	DB.Where("user_id = ?", req.UserId).Limit(5).Find(&CommonLocation)
	var list []*location.CommonLocation
	for _, c := range CommonLocation {
		var l = location.CommonLocation{
			Name:     c.NickName,
			Location: c.LetLng,
		}
		list = append(list, &l)
	}
	resp = &location.CommonLocationListResp{
		List: list,
	}
	return resp, nil
}
